package com.ltu.aop;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.ltu.base.State;
import com.ltu.model.request.CommonRequest;
import com.ltu.model.response.CodeResp;
import com.ltu.util.exception.MngException;


//2022 作废此方法验证参数
//@Aspect
//@Service
public class ControllerAop {

	private final static Logger logger = LoggerFactory.getLogger(ControllerAop.class);
	

	private static  ObjectMapper jsonMapper = new ObjectMapper();

    @Pointcut("execution(* com.ltu.controller..*.*(..))" + "&& !execution(* com.ltu.controller.ImgUploadController.*(..))"
			+ "&& !execution(* com.ltu.controller.payRecord.wxNotify(..))")
    public void webLog(){}
    
    @Around("webLog()")  
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
    	 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
         HttpServletRequest request = attributes.getRequest();
         // 记录下请求内容
         String requestStr =  "URL : " + request.getRequestURL().toString()+",HTTP_METHOD : " + request.getMethod()+",IP : " 
        		 + request.getRemoteAddr()+",CLASS_METHOD : " + pjp.getSignature().getDeclaringTypeName() + "." + pjp.getSignature().getName();
         logger.info(requestStr);
         Object result = null;
         Long startTime = System.currentTimeMillis();
         try {
	    	 Object[] params = pjp.getArgs();
	    	 for (int i = 0; i < params.length; i++) {
//	    		logger.info("请求参数：{}", jsonMapper.writeValueAsString(params[i]));
	         	if (params[i] instanceof CommonRequest) {
	         		CommonRequest requestData = (CommonRequest) params[i];
	 				/*State state = checkArgument(requestData);//TODO 加密认证
	 				if (state == null || !CodeRespUtils.Check_Argument.getCode().equals(state.getCode())) {
	 					logger.info("访问接口失败:校验码错误");
	 					return new CodeResp(CodeRespUtils.Invalid_Parameter);
	 				}*/
	         		Map<String,String> errors = CheckUtil.check(requestData);//参数认证
	 				if (!errors.isEmpty()) {
	 					for(String key: errors.keySet()){	 					
 							return new CodeResp(State.CODE_FAILED,key.concat(":"+errors.get(key)));
 						}
	 				}
	 				break;
	         	}
	         }
	        //System.out.println("进入执行方法");  
			result = pjp.proceed();//执行该方法  
		}catch (ConstraintViolationException ex) {//JSR303 BeanValidator的校验异常
			List<String> list = Lists.newArrayList();
			for (ConstraintViolation<?> constraintViolation : ex.getConstraintViolations()) {
				String message = constraintViolation.getMessage();
				list.add(message);
			}
			String body = list.toString();
			logger.warn("访问接口失败。原因：{}", body);
			return new CodeResp("300000", body);
		}catch (MngException e) {
			logger.warn("访问接口失败。原因：{}", e.getMessage());
			return new CodeResp(e.getCode(), e.getMessage());
		}catch (Exception e) {
			logger.error("访问接口失败。原因：{}，报文：{}", e.getMessage(), e);
			return new CodeResp("500000", e.getMessage());
		}
         long time = (System.currentTimeMillis() - startTime)/1000;
         if(time > 3){
         	logger.error("api执行时间 （秒）: " + time+"，请求头："+requestStr);
         }
        //System.out.println("退出执行方法");  
        return result;  
    }  
    

    @AfterReturning(returning = "ret", pointcut = "webLog()")
    public void doAfterReturning(Object ret) throws Throwable {

        logger.info("返回参数 : " + jsonMapper.writeValueAsString(ret));
    }
}

